This notebook computes the viewshed for each point in 'observer_points' based on an 'elevation' raster.
This notebook uses GRASS GIS (7.0.4), and must be run inside of a GRASS environment (start the jupyter notebook server from the GRASS command line). GRASS GIS
The code in this notebook was modified from examples in "How to write a Python GRASS GIS 7 addon" developed for a FOSS4G Europe 2015 workshop. The code is contained in the "python-grass-addon" repository on GitHub.com.
elevation – raster digital elevation model
observer_points – vector map contain observer points
observer_height – height in map units of observer above the elevation raster
In [ ]:
elevation = 'DEM'
observer_points = 'sample_points_field'
observer_elevation = 1.5
In [1]:
import numpy as np
import pandas
import pyprind
GRASS import statements
In [2]:
import grass.script as gscript
from grass.pygrass.vector.geometry import Point
from grass.pygrass.vector import Vector
from grass.pygrass.vector import VectorTopo
from grass.pygrass.vector.table import DBlinks
In [4]:
radius = -1 #default = -1 (infinity)
tmp_viewshed_name = 'tmp_viewshed'
tmp_point = 'tmp_current_point'
# connect to attributes table
sample_points = VectorTopo(observer_points)
sample_points.open(mode='r')
dblinks = DBlinks(sample_points.c_mapinfo)
link = dblinks[0]
sample_points_table = link.table()
sample_points_table.filters.select('cat', 'ID')
with Vector(observer_points, mode='r') as points:
progress_bar = pyprind.ProgBar(points.n_lines, bar_char='█', title='Viewshed progress', monitor=True, stream=1, width=50)
for point in points:
progress_bar.update(item_id = str(point.cat))
# get ID of point
sample_points_table.filters.where('cat = {0}'.format(point.cat))
cursor = sample_points_table.execute()
result = np.array(cursor.fetchall())
cursor.close()
data = pandas.DataFrame(result, columns=['cat', 'ID']).set_index('cat')
ID = data['ID'].get_value(point.cat)
# compute viewshed
viewshed_id = str(ID)
viewshed_name = viewshed_id + '_viewshed'
gscript.read_command('r.viewshed',
input=elevation,
observer_elevation=1.5,
output=tmp_viewshed_name,
coordinates=point.coords(),
overwrite=True)
gscript.mapcalc(exp="{viewshed} = if({tmp}, {vid}, null())".format(viewshed=viewshed_name,
tmp=tmp_viewshed_name,
vid=viewshed_id),
overwrite=True)
delete viewshed
In [ ]:
def delete_viewshed(name):
gscript.read_command('g.remove',
type='raster',
name=name,
flags='f')
view result
In [ ]:
# import a function to render the results
from render import view
from grass.pygrass.modules.shortcuts import raster as r
# set the colors of the input and output maps to a predefined elevation color table
#r.colors(map='DEM', color='elevation')
In [12]:
view(['8_viewshed'])
Out[12]: